# Copyright 2024 Henrique Paone
#
# This file is part of Ruby-tui.
#
# Ruby-tui is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
# 
# Ruby-tui is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License along with
# Ruby-tui. If not, see <https://www.gnu.org/licenses/>.

module Tui
  Ansi_regex = /\x1b\[[0-9;:]*[mGKHF]/ 
  Line_chars = { 
    hori:  "\u2500",
    vert:  "\u2502",
    ulcor: "\u250c",
    urcor: "\u2510",
    llcor: "\u2514",
    lrcor: "\u2518",
    rvert: "\u251c",
    lvert: "\u2524"
  }
  
  def move_cursor(line, col)
    printf "\e[%d;%dH", line, col
  end

  def move_cursor_left
    print "\e[D"
  end

  def hide_cursor
    print "\e[?25l"
  end
  
  def show_cursor
    print "\e[?25h"
  end

  def save_cursor
    print "\e7" 
  end

  def restore_cursor
    print "\e8"
  end

  def save_screen
    printf "\e[?1049h"
  end

  def restore_screen
    printf "\e[?1049l"
  end
  
  def redraw
    save_screen
    restore_screen
  end

  def clear_current_line
    print "\e[0K"
  end

  def erase_char
    printf "\e[1X"
  end

  def backspace
    move_cursor_left
    erase_char
  end

  def scroll_down(lines)
    print "\e[#{ lines }S"
  end
  
  def scroll_up(lines)
    print "\e[#{ lines }T"
  end

  # getch doesn't trigger signals, so we manually catch them
  def readc
    c = STDIN.getch
    Process.kill("INT", $$) if c == "\u0003"
    Process.kill("STOP", $$) if c == "\u001a"
    c
  end

  def print_centered(text, l, c, llim, rlim)
    text.split("\n").reject(&:empty?).each do |line|
      move_cursor(l, c)
      mbyte = line.chars.count do |char| char.bytesize > 1 end
      print line.center(rlim - llim - mbyte)
      l += 1
    end
    l
  end

  def print_line_before(text, line, col)
    text.reverse.each_char do |c|
      move_cursor(line, col)
      print c
      col -= 1
    end
  end

  def draw_vline_inbox(c1, c2, l)
    move_cursor(l, c1)
    print Line_chars[:rvert]
    draw_hline(c1 + 1, c2, l)
    print Line_chars[:lvert]
  end

  def draw_hline(c1, c2, l)
    move_cursor(l, c1)
    (c2 - c1).times do print Line_chars[:hori] end
  end
  
  def draw_vline(l1, l2, c)
    (l1..l2).each do |l|
      move_cursor(l, c)
      print Line_chars[:vert] 
    end
  end

  def draw_box(l1, c1, l2, c2)
    # Draw corners
    move_cursor(l1, c1)
    print Line_chars[:ulcor]
    move_cursor(l1, c2)
    print Line_chars[:urcor]
    move_cursor(l2, c1)
    print Line_chars[:llcor]
    move_cursor(l2, c2)
    print Line_chars[:lrcor]

    draw_hline(c1 + 1, c2, l1)
    draw_hline(c1 + 1, c2, l2)
    draw_vline(l1 + 1, l2 - 1, c1)
    draw_vline(l1 + 1, l2 - 1, c2)
  end
end
